package com.share.device.utils;

import com.share.device.constants.DeviceConstants;
import com.share.device.domain.Cabinet;
import com.share.device.domain.CabinetSlot;
import com.share.device.domain.PowerBank;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.HashMap;

/**
 * 设备管理工具类
 * 
 * @author         
 * @date 2025-06-24
 */
public class DeviceManagementUtils
{
    /**
     * 获取柜机状态描述
     * 
     * @param status 状态码
     * @return 状态描述
     */
    public static String getCabinetStatusDesc(String status) {
        switch (status) {
            case DeviceConstants.CabinetStatus.NOT_DEPLOYED:
                return "未投入";
            case DeviceConstants.CabinetStatus.IN_USE:
                return "使用中";
            case DeviceConstants.CabinetStatus.FAULT:
                return "故障";
            default:
                return "未知";
        }
    }

    /**
     * 获取充电宝状态描述
     * 
     * @param status 状态码
     * @return 状态描述
     */
    public static String getPowerBankStatusDesc(String status) {
        switch (status) {
            case DeviceConstants.PowerBankStatus.NOT_DEPLOYED:
                return "未投放";
            case DeviceConstants.PowerBankStatus.AVAILABLE:
                return "可用";
            case DeviceConstants.PowerBankStatus.RENTED:
                return "已租用";
            case DeviceConstants.PowerBankStatus.CHARGING:
                return "充电中";
            case DeviceConstants.PowerBankStatus.FAULT:
                return "故障";
            default:
                return "未知";
        }
    }

    /**
     * 获取插槽状态描述
     * 
     * @param status 状态码
     * @return 状态描述
     */
    public static String getSlotStatusDesc(String status) {
        switch (status) {
            case DeviceConstants.SlotStatus.FREE:
                return "空闲";
            case DeviceConstants.SlotStatus.OCCUPIED:
                return "占用";
            case DeviceConstants.SlotStatus.LOCKED:
                return "锁定";
            default:
                return "未知";
        }
    }

    /**
     * 检查柜机是否可以部署
     * 
     * @param cabinet 柜机
     * @return 是否可以部署
     */
    public static boolean canDeployCabinet(Cabinet cabinet) {
        return cabinet != null && 
               DeviceConstants.CabinetStatus.NOT_DEPLOYED.equals(cabinet.getStatus());
    }

    /**
     * 检查柜机是否可以维护
     * 
     * @param cabinet 柜机
     * @return 是否可以维护
     */
    public static boolean canMaintainCabinet(Cabinet cabinet) {
        return cabinet != null && 
               (DeviceConstants.CabinetStatus.IN_USE.equals(cabinet.getStatus()) ||
                DeviceConstants.CabinetStatus.FAULT.equals(cabinet.getStatus()));
    }

    /**
     * 检查充电宝是否可用
     * 
     * @param powerBank 充电宝
     * @return 是否可用
     */
    public static boolean isPowerBankAvailable(PowerBank powerBank) {
        return powerBank != null && 
               DeviceConstants.PowerBankStatus.AVAILABLE.equals(powerBank.getStatus()) &&
               powerBank.getElectricity() != null &&
               powerBank.getElectricity().compareTo(BigDecimal.valueOf(DeviceConstants.BusinessRules.MIN_ELECTRICITY_THRESHOLD)) >= 0;
    }

    /**
     * 检查插槽是否空闲
     * 
     * @param slot 插槽
     * @return 是否空闲
     */
    public static boolean isSlotFree(CabinetSlot slot) {
        return slot != null && 
               DeviceConstants.SlotStatus.FREE.equals(slot.getStatus());
    }

    /**
     * 计算柜机使用率
     * 
     * @param cabinet 柜机
     * @return 使用率（0-1之间的小数）
     */
    public static double calculateCabinetUsageRate(Cabinet cabinet) {
        if (cabinet == null || cabinet.getTotalSlots() == null || cabinet.getTotalSlots() == 0) {
            return 0.0;
        }
        return (double) cabinet.getUsedSlots() / cabinet.getTotalSlots();
    }

    /**
     * 计算充电宝平均电量
     * 
     * @param powerBanks 充电宝列表
     * @return 平均电量
     */
    public static BigDecimal calculateAverageElectricity(List<PowerBank> powerBanks) {
        if (powerBanks == null || powerBanks.isEmpty()) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal totalElectricity = powerBanks.stream()
            .map(PowerBank::getElectricity)
            .filter(electricity -> electricity != null)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        return totalElectricity.divide(BigDecimal.valueOf(powerBanks.size()), 2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 统计柜机插槽状态
     * 
     * @param slots 插槽列表
     * @return 状态统计Map
     */
    public static Map<String, Long> countSlotStatus(List<CabinetSlot> slots) {
        if (slots == null) {
            return new HashMap<>();
        }
        
        return slots.stream()
            .collect(Collectors.groupingBy(
                CabinetSlot::getStatus,
                Collectors.counting()
            ));
    }

    /**
     * 统计充电宝状态
     * 
     * @param powerBanks 充电宝列表
     * @return 状态统计Map
     */
    public static Map<String, Long> countPowerBankStatus(List<PowerBank> powerBanks) {
        if (powerBanks == null) {
            return new HashMap<>();
        }
        
        return powerBanks.stream()
            .collect(Collectors.groupingBy(
                PowerBank::getStatus,
                Collectors.counting()
            ));
    }

    /**
     * 检查电量是否在正常范围内
     * 
     * @param electricity 电量
     * @return 是否正常
     */
    public static boolean isElectricityNormal(BigDecimal electricity) {
        if (electricity == null) {
            return false;
        }
        
        return electricity.compareTo(BigDecimal.valueOf(DeviceConstants.BusinessRules.MIN_ELECTRICITY_THRESHOLD)) >= 0 &&
               electricity.compareTo(BigDecimal.valueOf(DeviceConstants.BusinessRules.MAX_ELECTRICITY_THRESHOLD)) <= 0;
    }

    /**
     * 生成充电宝编号
     * 
     * @param sequence 序列号
     * @return 充电宝编号
     */
    public static String generatePowerBankNo(Long sequence) {
        return DeviceConstants.BusinessRules.POWER_BANK_NO_PREFIX + String.format("%06d", sequence);
    }

    /**
     * 生成柜机编号
     * 
     * @param sequence 序列号
     * @return 柜机编号
     */
    public static String generateCabinetNo(Long sequence) {
        return DeviceConstants.BusinessRules.CABINET_NO_PREFIX + String.format("%06d", sequence);
    }

    /**
     * 验证设备编号格式
     * 
     * @param deviceNo 设备编号
     * @param deviceType 设备类型
     * @return 是否有效
     */
    public static boolean isValidDeviceNo(String deviceNo, String deviceType) {
        if (deviceNo == null || deviceType == null) {
            return false;
        }
        
        switch (deviceType) {
            case DeviceConstants.DeviceType.POWER_BANK:
                return deviceNo.startsWith(DeviceConstants.BusinessRules.POWER_BANK_NO_PREFIX);
            case DeviceConstants.DeviceType.CABINET:
                return deviceNo.startsWith(DeviceConstants.BusinessRules.CABINET_NO_PREFIX);
            default:
                return false;
        }
    }
} 